package com.tianqu.tms.core.util;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import com.google.common.base.Joiner;

/**
 *
 * @author Wei Huang
 */
public class SMSUtil {
	//
	private static final Log LOGGER = LogFactory.getLog(SMSUtil.class);
	private static final String DELIMITER = ",";
	private static final String SP_CODE = "243165";
	private static final String LOGIN_NAME = "dl_thkj";
	private static final String PASSWORD = "tianqukeji*8";
	private static final String URL = "https://api.ums86.com:9600/sms/Api/Send.do";
	private static final String CONTENT_TYPE = "application/x-www-form-urlencoded;charset=gbk";

	/**
	 *
	 * @param mobile
	 * @param content
	 * @return
	 */
	public static boolean send(final String mobile, String content) throws Exception {
		return _send(mobile, content);
	}

	public static boolean send(final ArrayList<String> mobiles, String content) throws Exception {
		if (mobiles == null || mobiles.size() == 0) return false;
		return _send(Joiner.on(DELIMITER).join(mobiles), content);
	}

	/**
	 *
	 * @param mobile
	 * @param content
	 * @return
	 */
	private static boolean _send(final String mobile, String content) throws Exception{
		boolean isSuccess = false;
		final CloseableHttpClient httpclient = HttpClients.createDefault();
		try {
			final HttpPost httpPost = new HttpPost(new URI(URL));
			httpPost.setHeader(HTTP.CONTENT_TYPE, CONTENT_TYPE);
			List <NameValuePair> params = build(mobile, content);
			httpPost.setEntity(new UrlEncodedFormEntity(params, "gbk"));
			final String response = httpclient.execute(httpPost, getHandler());
			LOGGER.info("received response:" + response);
			//
			final Response res = Response.parse(response);
			isSuccess = res.getResult() == "0";
			if (!isSuccess) {
				LOGGER.error("send sms failed, " +
						"mobile=" + mobile + "," +
						"content=" + content + "," +
						"error code=" + res.getResult() + "," +
						"error desc=" + res.getDescription());
			}
		} catch (IOException iox) {
			LOGGER.error("encountered exception, ", iox);
		} catch (URISyntaxException usx) {
			LOGGER.error("encountered uri exception, ", usx);
		} catch (Exception ex) {
			LOGGER.error("encountered unknown exception", ex);
		} finally {
			httpclient.close();
		}

		return isSuccess;
	}

	private static List<NameValuePair> build(String mobile, String content) {
		final List<NameValuePair> r = new ArrayList();
		BasicNameValuePair f = new BasicNameValuePair("f", "1");
		BasicNameValuePair spCode = new BasicNameValuePair("SpCode", SP_CODE);
		BasicNameValuePair password = new BasicNameValuePair("Password", PASSWORD);
		BasicNameValuePair loginName = new BasicNameValuePair("LoginName", LOGIN_NAME);
		BasicNameValuePair serialNumber = new BasicNameValuePair("SerialNumber", "12345678901234567890");
		BasicNameValuePair scheduleTime = new BasicNameValuePair("ScheduleTime", "");
		BasicNameValuePair userNumber = new BasicNameValuePair("UserNumber", mobile);
		BasicNameValuePair messageContent = new BasicNameValuePair("MessageContent", content);
		r.add(serialNumber); r.add(scheduleTime); r.add(userNumber); r.add(messageContent); r.add(f); r.add(spCode); r.add(password); r.add(loginName); return r;
	}

	/**
	 *
	 */
	private static ResponseHandler<String> getHandler() {
		return new ResponseHandler<String>(){
			@Override
			public String handleResponse(HttpResponse response) throws IOException {
				int status = response.getStatusLine().getStatusCode();
				if (status >= 200 && status < 300) {
					final HttpEntity entity = response.getEntity();
					return entity != null ? new String(EntityUtils.toString(entity).getBytes("ISO-8859-1"), "gbk")  : null;
				} else {
					throw new ClientProtocolException("Unexpected response status: " + status);
				}
			}
		};
	}

	/**
	 *
	 */
	private static class Response {
		String result;
		String taskid;
		String faillist;
		String description;

		public String getResult() {
			return result;
		}

		public void setResult(String result) {
			this.result = result;
		}

		public String getTaskid() {
			return taskid;
		}

		public void setTaskid(String taskid) {
			this.taskid = taskid;
		}

		public String getFaillist() {
			return faillist;
		}

		public void setFaillist(String faillist) {
			this.faillist = faillist;
		}

		public String getDescription() {
			return description;
		}

		public void setDescription(String description) {
			this.description = description;
		}
		public static Response parse(String raw) {
			final Response r = new Response();
			final List<NameValuePair> params = URLEncodedUtils.parse(raw, Charset.forName("gbk"));
			for (NameValuePair pair : params) {
				if (pair.getName().equals("result")) r.setResult(pair.getValue());
				if (pair.getName().equals("taskid")) r.setTaskid(pair.getValue());
				if (pair.getName().equals("faillist")) r.setFaillist(pair.getValue());
				if (pair.getName().equals("description")) r.setDescription(pair.getValue());
			}
			return r;
		}
	}

	public static void main(String args[]) throws Exception {
		//test1
//		final ArrayList<String> targets = new ArrayList(2);
//		targets.add("13840935981"); targets.add("13164508981");
//		send(targets, "电话为13888888888购买了一台奔驰G500请注意回访。");
		//test2
		boolean r = send("15542303187", "电话为15542303187的客户购买了一台拖拉机请注意回访");
	}
}
